package com.virtualightning.mvvm.impl.adapter

import android.util.Log
import com.virtualightning.mvvm.tools.SyncCode
import java.util.*

/**
 *  Anchor : Create by CimZzz
 *  Time : 2021/11/15 11:46
 *  数据变化缓存池
 */
internal class DataChangedCacheMap {
	/**
	 * 数据变化同步码
	 */
	private val changedSyncCode = SyncCode()

	/**
	 * 数据缓存表
	 */
	private var dataCacheList: LinkedList<CacheItem>? = null


	///////////////////////////////////////////////////////////////////////////
	// 代码分割线 on 2021/11/15 11:47 上午 by CimZzz
	// 以下内容为:
	// 对外访问方法
	///////////////////////////////////////////////////////////////////////////

	/**
	 * 获取当前同步码
	 * @return Int 同步码
	 */
	fun getCurrentCode(): Int = changedSyncCode.currentCode()

	/**
	 * 配置观察者
	 * @param observer DataChangedObserver 数据变化观察者
	 */
	fun configObserver(observer: DataChangedObserver) {
		observer.onDataChangeCode(changedSyncCode.currentCode())
	}

	/**
	 * 数据发生变化了
	 * @param key String 消息键值
	 * @param data Any? 数据
	 * @param totalSize Int 数据总数
	 */
	fun dataChanged(key: String, data: Any?, totalSize: Int) {
		val newCode = changedSyncCode.nextCode()
		val newCacheItem = CacheItem(newCode, totalSize, key, data)
		val dataCacheList = this.dataCacheList ?: LinkedList<CacheItem>().let {
			this.dataCacheList = it
			it
		}
		dataCacheList.removeAll { it.key == key }
		dataCacheList.addFirst(newCacheItem)
	}

	/**
	 * 处理数据变化
	 * @param observer DataChangedObserver 数据变化观察者
	 */
	fun handleDataChanged(observer: DataChangedObserver) {
		val cacheList = dataCacheList ?: return
		val observerCode = observer.getDataChangeCode()
		if(changedSyncCode.checkCode(observerCode)) {
			// 数据同步，直接返回
			return
		}
		observer.onDataChangeCode(changedSyncCode.currentCode())
		val iterator = cacheList.iterator()

		val firstItem = cacheList.first
		val latestItem = cacheList.last
		if(firstItem.syncCode > latestItem.syncCode) {
			// SyncCode 重置了
			if(observerCode > latestItem.syncCode) {
				// 从头开始找
				while(iterator.hasNext()) {
					val item = iterator.next()
					if(item.syncCode <= observerCode) {
						continue
					}
					observer.onDataChanged(item.key, item.data)
					if(item.totalCount == 1) {
						iterator.remove()
					}
					else {
						item.totalCount -= 1
					}
				}
			}
			else {
				// 从末尾开始找
				while (iterator.hasNext()) {
					val item = iterator.next()
					if(item.syncCode > latestItem.syncCode) {
						continue
					}
					if(item.syncCode <= observerCode) {
						continue
					}
					observer.onDataChanged(item.key, item.data)
					if(item.totalCount == 1) {
						iterator.remove()
					}
					else {
						item.totalCount -= 1
					}
				}
			}
		} else {
			// SyncCode 未重置
			if(observerCode > latestItem.syncCode) {
				while(iterator.hasNext()) {
					val item = iterator.next()
					observer.onDataChanged(item.key, item.data)
					if(item.totalCount == 1) {
						iterator.remove()
					}
					else {
						item.totalCount -= 1
					}
				}
			}
			else {
				while(iterator.hasNext()) {
					val item = iterator.next()
					if(item.syncCode <= observerCode) {
						continue
					}
					observer.onDataChanged(item.key, item.data)
					if(item.totalCount == 1) {
						iterator.remove()
					}
					else {
						item.totalCount -= 1
					}
				}
			}
		}

		if(cacheList.isEmpty()) {
			Log.v("CimZzz", "空啦1")
			dataCacheList = null
		}



	}

	/**
	 * 回收全部资源
	 */
	fun clear() {
		this.dataCacheList = null
	}

	/**
	 * 数据变化回调
	 */
	internal interface DataChangedObserver {

		/**
		 * 保存数据同步码
		 * @param code Int 数据同步码
		 */
		fun onDataChangeCode(code: Int)

		/**
		 * 获取数据同步码
		 * @return Int 数据同步码
		 */
		fun getDataChangeCode(): Int

		/**
		 * 数据变化回调
		 * @param key String
		 * @param data Any?
		 */
		fun onDataChanged(key: String, data: Any?)
	}

	/**
	 * 缓存的数据对象
	 * @property syncCode Int 同步码
	 * @property totalCount Int 总数
	 * @property key String 键值
	 * @property data Any? 数据
	 * @constructor
	 */
	private data class CacheItem (
		var syncCode: Int,
		var totalCount: Int,
		var key: String,
		var data: Any? = null,
	)
}